package com.star.percalservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.star.percalservice.mapper.*;
import com.star.percalservice.model.entity.*;
import com.star.percalservice.model.vo.DashboardDataVO;
import com.star.percalservice.service.HomeDataService;
import com.star.percalservice.service.ScoreRuleService;
import com.star.percalservice.utils.MyDateUtil;
import com.star.percalservice.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author star
 * @version 1.0
 * @Description:
 * @DateTime 2025/4/12 5:23
 */

@Service
public class HomeDataServiceImpl implements HomeDataService {

    @Autowired
    private ResearchProjectMapper researchProjectMapper;
    @Autowired
    private PaperMapper paperMapper;
    @Autowired
    private PatentMapper patentMapper;
    @Autowired
    private AwardMapper awardMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private ScoreRuleService scoreRuleService;

    private static final String status = "approved";

    @Override
    public R getHomeData() {
        DashboardDataVO dashboardDataVO = new DashboardDataVO();
        // 统计用户数量
        DashboardDataVO.UserStats userStats = getUserStats();
        // 科研、论文、专利、获奖数量
        DashboardDataVO.ResearchStats researchStats = getResearchStats();
        // 月度科研业绩统计
        List<DashboardDataVO.MonthlyStat> monthlyStats = getMonthlyStats();
        // 院系统计数据
        List<DashboardDataVO.DepartmentStat> departmentStats = getDepartmentStats();
        // 最近活动
        List<DashboardDataVO.RecentActivity> recentActivity = getRecentActivity();
        // 绩效排名
        List<DashboardDataVO.PerformanceRanking> performanceRanking = getPerformanceRanking();
        // 返回数据
        dashboardDataVO.setUserStats(userStats);
        dashboardDataVO.setResearchStats(researchStats);
        dashboardDataVO.setMonthlyStats(monthlyStats);
        dashboardDataVO.setDepartmentStats(departmentStats);
        dashboardDataVO.setRecentActivity(recentActivity);
        dashboardDataVO.setPerformanceRanking(performanceRanking);
        Map<String, Object> data = new HashMap<>();
        data.put("data", dashboardDataVO);
        return R.ok("查询成功", data);
    }

    @Override
    public R getTeacherData(Integer tid) {
        QueryWrapper<ResearchProject> researchProjectQueryWrapper = new QueryWrapper<>();
        researchProjectQueryWrapper.eq("status", status);
        researchProjectQueryWrapper.eq("teacher_id", tid);
        List<ResearchProject> projectList = researchProjectMapper.selectList(researchProjectQueryWrapper);
        QueryWrapper<Paper> paperQueryWrapper = new QueryWrapper<>();
        paperQueryWrapper.eq("status", status);
        paperQueryWrapper.eq("teacher_id", tid);
        List<Paper> paperList = paperMapper.selectList(paperQueryWrapper);
        QueryWrapper<Patent> patentQueryWrapper = new QueryWrapper<>();
        patentQueryWrapper.eq("status", status);
        patentQueryWrapper.eq("teacher_id", tid);
        List<Patent> patentList = patentMapper.selectList(patentQueryWrapper);
        QueryWrapper<Award> awardQueryWrapper = new QueryWrapper<>();
        awardQueryWrapper.eq("status", status);
        awardQueryWrapper.eq("teacher_id", tid);
        List<Award> awardList = awardMapper.selectList(awardQueryWrapper);
        Map<String, Object> data = new HashMap<>();
        data.put("projectList", projectList);
        data.put("paperList", paperList);
        data.put("patentList", patentList);
        data.put("awardList", awardList);
        return R.ok("查询成功", data);
    }

    private DashboardDataVO.UserStats getUserStats() {
        // 获取总用户数量
        Integer totalUsers = Math.toIntExact(userMapper.selectCount(null));
        // 获取教师数量
        Integer teacherCount = Math.toIntExact(userMapper.selectCount(new QueryWrapper<User>().eq("role", "teacher")));
        // 获取管理员数量
        Integer adminCount = Math.toIntExact(userMapper.selectCount(new QueryWrapper<User>().eq("role", "admin")));
        return new DashboardDataVO.UserStats(totalUsers, teacherCount, adminCount);
    }

    private DashboardDataVO.ResearchStats getResearchStats() {
        // 科研项目统计 状态为已通过的
        QueryWrapper<ResearchProject> researchProjectQueryWrapper = new QueryWrapper<>();
        researchProjectQueryWrapper.eq("status", status);
        Integer totalProjects = Math.toIntExact(researchProjectMapper.selectCount(researchProjectQueryWrapper));
        // 论文统计
        QueryWrapper<Paper> paperQueryWrapper = new QueryWrapper<>();
        paperQueryWrapper.eq("status", status);
        Integer totalPapers = Math.toIntExact(paperMapper.selectCount(paperQueryWrapper));
        // 专利统计
        QueryWrapper<Patent> patentQueryWrapper = new QueryWrapper<>();
        patentQueryWrapper.eq("status", status);
        Integer totalPatents = Math.toIntExact(patentMapper.selectCount(patentQueryWrapper));
        // 获奖统计
        QueryWrapper<Award> awardQueryWrapper = new QueryWrapper<>();
        awardQueryWrapper.eq("status", status);
        Integer totalAwards = Math.toIntExact(awardMapper.selectCount(awardQueryWrapper));

        // 返回数据
        return new DashboardDataVO.ResearchStats(totalProjects, totalPapers, totalPatents, totalAwards);
    }

    private List<DashboardDataVO.MonthlyStat> getMonthlyStats() {
        List<DashboardDataVO.MonthlyStat> monthlyStats = new ArrayList<>();
        // 获取前12月的数据
        List<String> months = MyDateUtil.getLastNMonths(12);
        months.forEach(month -> {
            DashboardDataVO.MonthlyStat monthlyStat = new DashboardDataVO.MonthlyStat();
            monthlyStat.setMonth(month);
            // 获取月份的开始和结束日期
            String startDate = MyDateUtil.getMonthStartDate(month);
            String endDate = MyDateUtil.getMonthEndDate(month);
            // 获取科研项目数量
            QueryWrapper<ResearchProject> researchProjectQueryWrapper = new QueryWrapper<>();
            researchProjectQueryWrapper.between("start_date", startDate, endDate);
            researchProjectQueryWrapper.eq("status", status);
            Integer projects = Math.toIntExact(researchProjectMapper.selectCount(researchProjectQueryWrapper));
            monthlyStat.setProjects(projects);
            // 获取论文数量
            QueryWrapper<Paper> paperQueryWrapper = new QueryWrapper<>();
            paperQueryWrapper.between("publish_date", startDate, endDate);
            paperQueryWrapper.eq("status", status);
            Integer papers = Math.toIntExact(paperMapper.selectCount(paperQueryWrapper));
            monthlyStat.setPapers(papers);
            // 获取专利数量
            QueryWrapper<Patent> patentQueryWrapper = new QueryWrapper<>();
            patentQueryWrapper.between("authorization_date", startDate, endDate);
            patentQueryWrapper.eq("status", status);
            Integer patents = Math.toIntExact(patentMapper.selectCount(patentQueryWrapper));
            monthlyStat.setPatents(patents);
            // 获取获奖数量
            QueryWrapper<Award> awardQueryWrapper = new QueryWrapper<>();
            awardQueryWrapper.between("award_date", startDate, endDate);
            awardQueryWrapper.eq("status", status);
            Integer awards = Math.toIntExact(awardMapper.selectCount(awardQueryWrapper));
            monthlyStat.setAwards(awards);
            monthlyStats.add(monthlyStat);
        });
        return monthlyStats;
    }

    private List<DashboardDataVO.DepartmentStat> getDepartmentStats() {
        List<DashboardDataVO.DepartmentStat> departmentStats = new ArrayList<>();
        // 先获取所有院系名称
        List<Teacher> teacherList = teacherMapper.selectList(null);
        // 去除重复的院系名称
        Set<String> departments = teacherList.stream().map(Teacher::getDepartment).collect(Collectors.toSet());
        // 遍历院系名称，获取科研项目、论文、专利、获奖数量
        departments.forEach(department -> {
            DashboardDataVO.DepartmentStat departmentStat = new DashboardDataVO.DepartmentStat();
            departmentStat.setDepartment(department);
            // 根据院系名称获取教师Id集合
            QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
            teacherQueryWrapper.eq("department", department);
            List<Teacher> teachers = teacherMapper.selectList(teacherQueryWrapper);
            List<Integer> teacherIds = teachers.stream().map(Teacher::getId).toList();
            // 根据教师Id集合获取科研项目、论文、专利、获奖数量
            QueryWrapper<ResearchProject> researchProjectQueryWrapper = new QueryWrapper<>();
            researchProjectQueryWrapper.in("teacher_id", teacherIds);
            researchProjectQueryWrapper.eq("status", status);
            Integer projects = Math.toIntExact(researchProjectMapper.selectCount(researchProjectQueryWrapper));
            departmentStat.setProjects(projects);
            QueryWrapper<Paper> paperQueryWrapper = new QueryWrapper<>();
            paperQueryWrapper.in("teacher_id", teacherIds);
            paperQueryWrapper.eq("status", status);
            Integer papers = Math.toIntExact(paperMapper.selectCount(paperQueryWrapper));
            departmentStat.setPapers(papers);
            QueryWrapper<Patent> patentQueryWrapper = new QueryWrapper<>();
            patentQueryWrapper.in("teacher_id", teacherIds);
            patentQueryWrapper.eq("status", status);
            Integer patents = Math.toIntExact(patentMapper.selectCount(patentQueryWrapper));
            departmentStat.setPatents(patents);
            QueryWrapper<Award> awardQueryWrapper = new QueryWrapper<>();
            awardQueryWrapper.in("teacher_id", teacherIds);
            awardQueryWrapper.eq("status", status);
            Integer awards = Math.toIntExact(awardMapper.selectCount(awardQueryWrapper));
            departmentStat.setAwards(awards);
            departmentStats.add(departmentStat);
        });
        return departmentStats;
    }

    private List<DashboardDataVO.RecentActivity> getRecentActivity() {
        // 步骤1：获取各类型数据并转换为统一的活动对象
        List<DashboardDataVO.RecentActivity> activities = new ArrayList<>();

        // 获取科研项目数据
        QueryWrapper<ResearchProject> researchProjectQueryWrapper = new QueryWrapper<>();
        researchProjectQueryWrapper.orderByDesc("start_date");
        researchProjectQueryWrapper.last("limit 5");
        List<ResearchProject> researchProjects = researchProjectMapper.selectList(researchProjectQueryWrapper);
        researchProjects.forEach(researchProject -> {
            DashboardDataVO.RecentActivity activity = new DashboardDataVO.RecentActivity(
                    researchProject.getId(),
                    "project",
                    researchProject.getName(),
                    getTeacherName(researchProject.getTeacherId()),
                    researchProject.getStartDate(),
                    researchProject.getStatus()
            );
            activities.add(activity);
        });
        // 获取论文数据
        QueryWrapper<Paper> paperQueryWrapper = new QueryWrapper<>();
        paperQueryWrapper.orderByDesc("publish_date");
        paperQueryWrapper.last("limit 5");
        List<Paper> papers = paperMapper.selectList(paperQueryWrapper);
        papers.forEach(paper -> {
            DashboardDataVO.RecentActivity activity = new DashboardDataVO.RecentActivity(
                    paper.getId(),
                    "paper",
                    paper.getTitle(),
                    getTeacherName(paper.getTeacherId()),
                    paper.getPublishDate(),
                    paper.getStatus()
            );
            activities.add(activity);
        });
        // 获取专利数据
        QueryWrapper<Patent> patentQueryWrapper = new QueryWrapper<>();
        patentQueryWrapper.orderByDesc("authorization_date");
        patentQueryWrapper.last("limit 5");
        List<Patent> patents = patentMapper.selectList(patentQueryWrapper);
        patents.forEach(patent -> {
            DashboardDataVO.RecentActivity activity = new DashboardDataVO.RecentActivity(
                    patent.getId(),
                    "patent",
                    patent.getName(),
                    getTeacherName(patent.getTeacherId()),
                    patent.getAuthorizationDate(),
                    patent.getStatus()
            );
            activities.add(activity);
        });
        // 获取获奖数据
        QueryWrapper<Award> awardQueryWrapper = new QueryWrapper<>();
        awardQueryWrapper.orderByDesc("award_date");
        awardQueryWrapper.last("limit 5");
        List<Award> awards = awardMapper.selectList(awardQueryWrapper);
        awards.forEach(award -> {
            DashboardDataVO.RecentActivity activity = new DashboardDataVO.RecentActivity(
                    award.getId(),
                    "award",
                    award.getName(),
                    getTeacherName(award.getTeacherId()),
                    award.getAwardDate(),
                    award.getStatus()
            );
            activities.add(activity);
        });
        // 步骤2：对活动进行排序，按照时间降序排列,只取前8个
        activities.sort((o1, o2) -> o2.getDate().compareTo(o1.getDate()));
        return activities.subList(0, Math.min(activities.size(), 8));
    }

    private List<DashboardDataVO.PerformanceRanking> getPerformanceRanking() {
        // 根据教师Id进行分组，统计每个教师科研项目、论文、专利、获奖数量
        List<DashboardDataVO.PerformanceRanking> performanceRankings = new ArrayList<>();
        Map<String, Object> teacherResMap = new HashMap<>();
        teacherMapper.selectList(null).forEach(teacher -> {
            // 根据id为key，将总分数存入map中
            teacherResMap.put(teacher.getId().toString(), scoreRuleService.calculateScore(teacher.getId()));
        });
        // 根据总分数进行排序，只取前8名
        List<Map.Entry<String, Object>> list = new ArrayList<>(teacherResMap.entrySet());
        list.sort((o1, o2) -> {
            Double score1 = (Double) o1.getValue();
            Double score2 = (Double) o2.getValue();
            return score2.compareTo(score1);
        });
        // 获取前8名
        for (int i = 0; i < list.size() && i < 8; i++) {
            Map.Entry<String, Object> entry = list.get(i);
            String teacherId = entry.getKey();
            Double score = (Double) entry.getValue();
            // 根据教师Id获取教师姓名
            String teacherName = getTeacherName(Integer.valueOf(teacherId));
            // 根据教师Id获取所属学院
            String department = teacherMapper.selectById(Integer.valueOf(teacherId)).getDepartment();
            performanceRankings.add(new DashboardDataVO.PerformanceRanking(i + 1, teacherName, department, score));
        }
        return performanceRankings.subList(0, Math.min(performanceRankings.size(), 8));
    }

    private String getTeacherName(Integer teacherId) {
        QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
        teacherQueryWrapper.eq("id", teacherId);
        Teacher teacher = teacherMapper.selectOne(teacherQueryWrapper);
        // 根据教师Id获取教师姓名
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("id", teacher.getUserId());
        User user = userMapper.selectOne(userQueryWrapper);
        return user.getRealName();
    }

}
